package ru.spb.osll.myfit.server.execute;

import org.apache.log4j.Logger;

import com.google.gwt.user.client.Window;

import fit.Counts;
import fit.Fixture;
import fit.FixtureLoader;
import fit.Parse;
import fitnesse.WikiPageFactory;
import fitnesse.html.SetupTeardownIncluder;
import fitnesse.wiki.FileSystemPage;
import fitnesse.wiki.PageData;
import fitnesse.wiki.PathParser;
import fitnesse.wiki.WikiPage;
import fitnesse.wiki.WikiPagePath;

public class FitNesseTestRunner {
	private Logger log = Logger.getLogger(getClass());
	protected WikiPage m_root;
	private FixtureLoader m_fixtureLoader;

	private ProgressFixtureListener m_fixtureListener;

	public FitNesseTestRunner(String rootPath, String rootDirectoryName,
			FixtureLoader fixtureLoader, ProgressFixtureListener listener)
			throws Exception {
		this(rootPath, rootDirectoryName, new WikiPageFactory(), fixtureLoader,
				listener);
	}

	public FitNesseTestRunner(String rootPath, String rootDirectoryName,
			WikiPageFactory wikiPageFactory, FixtureLoader fixtureLoader,
			ProgressFixtureListener listener) throws Exception {
		m_root = createRoot(rootPath, rootDirectoryName);
		m_fixtureLoader = fixtureLoader;
		m_fixtureListener = listener;
	}

	protected WikiPage createRoot(String rootPath, String rootDirectoryName) throws Exception {
		return new FileSystemPage(rootPath, rootDirectoryName);
	}

	public void run(String pagePath) throws Exception {
		log.info("Executing test " + pagePath);
		WikiPagePath path = PathParser.parse(pagePath);
		WikiPage page = m_root.getPageCrawler().getPage(m_root, path);
		PageData pageData = page.getData();
		// Execute SetUp and TearDown
		SetupTeardownIncluder.includeInto(pageData);
		String html = pageData.getHtml();
		Parse tables = new Parse(html);
		MyFitFixtureRunner fixtureRunner = new MyFitFixtureRunner(m_fixtureLoader, m_fixtureListener);		
		Counts counts = new Counts();

		try {
			fixtureRunner.doTables(tables);
		} catch (Exception e) {
			exception(fixtureRunner, counts, e);
		}
		
		if(m_fixtureLoader instanceof MyFitFixtureLoader){
			((MyFitFixtureLoader)m_fixtureLoader).close();
		}
	}

	private void exception(Fixture fixture, Counts counts, Exception e) {
		counts.exceptions = counts.exceptions + 1;
		Parse tables = new Parse("span", "Exception occurred: ", null, null);
		fixture.exception(tables, e);
		fixture.listener.tableFinished(tables);
		fixture.listener.tablesFinished(counts);
		Window.alert("Counts: "+counts.toString() + " Exception" + e.toString());
	}

}